package net.zoneland.zrdp.biz.service.impl;

import net.zoneland.uniflow.client.*;
import net.zoneland.zrdp.biz.common.Constants;
import net.zoneland.zrdp.biz.domain.pojo.query.TaskQuery;
import net.zoneland.zrdp.biz.domain.pojo.vo.ItemInfo;
import net.zoneland.zrdp.biz.enums.BusinessprocessEnum;
import net.zoneland.zrdp.biz.enums.ProcessStatusThree;
import net.zoneland.zrdp.biz.mapstruct.QueryParamConverter;
import net.zoneland.zrdp.biz.service.IWorkOrderService;
import net.zoneland.zrdp.common.core.page.Pager;
import net.zoneland.zrdp.framework.web.domain.uniflow.ReadObjectPojo;
import net.zoneland.zrdp.framework.web.domain.uniflow.TaskObjectPojo;
import net.zoneland.zrdp.framework.web.service.uniflow.WorkFlowService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class WorkOrderServiceImpl implements IWorkOrderService {
    @Resource
    private WorkFlowService uniFlowService;

    /**
     * 查询工单任务.
     * TaskQuery 中的状态条件：
     * FINISH、STOP、SINGLE_ASSIGNMENT 状态为已办；
     * READY、ASSIGNED 状态为待办；
     * DRAFT 状态为草稿；
     * READY、FINISH、DRAFT、ASSIGNED 状态为我的工单；
     * @param taskQuery 任务查询参数.
     * @param isApplyTask 是否最新任务.true：（每条工单取一条最新的已办）
     * @return 对应的结果
     **/
    @Override
    public Pager<TaskObjectPojo> queryTask(final TaskQuery taskQuery, final boolean isApplyTask) {
        final TaskQueryParam param = QueryParamConverter.INSTANCE.taskQueryToTaskParam(taskQuery);
        //查询工单任务
        final Integer page = taskQuery.getPageNum();
        final Integer rows = taskQuery.getPageSize();
        return isApplyTask
            ? uniFlowService.transformTasksToPager(getApplyTaskPage(param, page, rows))
            : uniFlowService.transformTasksToPager(getTaskPage(param, page, rows));
    }

    /**
     * 查询任务数据量.
     * TaskQuery 中的状态条件：
     * FINISH、STOP、SINGLE_ASSIGNMENT 状态为已办；
     * READY、ASSIGNED 状态为待办；
     * DRAFT 状态为草稿；
     * READY、FINISH、DRAFT、ASSIGNED 状态为我的工单；
     * @param param 查询条件
     * @return 任务数量
     */

    private Integer getTaskCount(final TaskQueryParam param ) {
        return uniFlowService.queryTasksCount(param);
    }

    /**
     * 查询待办数据量.
     * @param userName 用户名oaId
     * @return 待办数据量
     */
    @Override
    public Integer getTaskCount(final String userName) {
        final TaskQueryParam param = new TaskQueryParam();
        param.setStates(Constants.READY_ASSIGNED_STATES);
        param.setOwner(userName);
        return getTaskCount(param);
    }
    /**
     * 查询待阅数据量.
     * TaskQuery 中的状态条件：
     * FINISH、STOP、SINGLE_ASSIGNMENT 状态为已阅；
     * READY、ASSIGNED 状态为待阅；
     * @param param 查询条件
     * @return 任务数量
     */

    private Integer getReadCount(final ReadQueryParam param) {
        return uniFlowService.queryReadCount(param);
    }
    /**
     * 查询待阅数据量.
     * @param userName 用户名oaId
     * @return 待阅数量
     */
    @Override
    public Integer getReadCount(final String userName) {
        final ReadQueryParam param = new ReadQueryParam();
        param.setStates(Constants.READY_ASSIGNED_STATES);
        param.setOwner(userName);
        return getReadCount(param);
    }


    /**
     * 查询工单任务列表.带补全当前节点状态
     * @param taskQuery 任务查询参数.
     * @param isApplyTask 是否最新任务.true：（每条工单取一条最新的已办）
     * @return 对应的结果
     */
    @Override
    public Pager<TaskObjectPojo> queryTaskWithCurrentNodeName(final TaskQuery taskQuery, final boolean isApplyTask) {
        final Pager<TaskObjectPojo> pager = queryTask(taskQuery, isApplyTask);
        batchSetCurrentNodeName(pager.getList());
        return pager;
    }

    /**
     * 待阅或已阅任务列表.
     * TaskQuery 中的状态条件：
     * FINISH、STOP、SINGLE_ASSIGNMENT 状态为已阅；
     * READY、ASSIGNED 状态为待阅；
     * @param taskQuery 任务查询参数.
     * @return 待阅或已阅任务列表
     **/
    @Override
    public Pager<ReadObjectPojo> queryRead(final TaskQuery taskQuery) {
        final ReadQueryParam param = QueryParamConverter.INSTANCE.taskQueryToReadParam(taskQuery);
        //查询待阅任务
        final ReadPageObject readPageObject = getReadPage(param, taskQuery.getPageNum(), taskQuery.getPageSize());
        return uniFlowService.transformReadTasksToPager(readPageObject);
    }

    /**
     * 待阅,已阅分页任务查询.
     * @param readQuery 任务查询参数.
     * @param page 页数.
     * @param rows 每页的大小.
     * @return 结果对象
     **/
    private ReadPageObject getReadPage(final ReadQueryParam readQuery, final Integer page, final Integer rows) {
        return uniFlowService.queryReadsByPage(readQuery, page, rows);
    }

    /**
     * 待办,已办分页任务查询.
     * @param taskQuery 任务查询参数.
     * @param page 页数.
     * @param rows 每页的大小.
     * @return 结果对象
     **/
    private TaskPageObject getTaskPage(final TaskQueryParam taskQuery, final Integer page, final Integer rows) {
        return uniFlowService.queryTasksByPage(taskQuery, page, rows);
    }

    /**
     * 待办,已办分页最新任务查询.（每条工单取一条最新的已办）
     * @param taskQuery 任务查询参数.
     * @param page 页数.
     * @param rows 每页的大小.
     * @return 结果对象
     **/
    private ApplyTaskPageObject getApplyTaskPage(final TaskQueryParam taskQuery, final Integer page,
                                                 final Integer rows) {
        return uniFlowService.queryFinishedApplyTasksByPage(taskQuery, page, rows);
    }

    /**
     * 批量设置当前节点状态.
     * @param taskObjectPojoList 从流程平台获取的已处理待办.
     **/
    private void batchSetCurrentNodeName(final List<TaskObjectPojo> taskObjectPojoList) {
        Optional.ofNullable(taskObjectPojoList)
            .filter(CollectionUtils::isNotEmpty)
            .map(Collection::stream)
            .orElseGet(Stream::empty)
            .forEach(this::setTaskObjectPojo);
    }

    /**
     * 补全任务信息.
     * @param taskObjectPojo 任务信息.
     **/
    private void setTaskObjectPojo(final TaskObjectPojo taskObjectPojo) {
        // 查询流程当前信息.
        final ProcessCurrentObject processCurrentObject =
            uniFlowService.queryProcessCurrentInfo(taskObjectPojo.getPiid());

        // 流程实例信息.
        final ProcessObject processObject = processCurrentObject.getProcess();
        // 获取当前流程编码下所有待办.
        final TaskObject[] taskObjects = processCurrentObject.getReadyTasks();
        final String currentNodeName = Arrays.stream(taskObjects)
            .filter(x -> !StringUtils.equals(x.getOwner().getUserId(), Constants.ROLE_ADMIN))
            .map(TaskObject::getNodeName)
            .distinct()
            .collect(Collectors.joining(Constants.SPLIT_COMMA));

        // 当taskObjects列表为空时获取流程状态
        taskObjectPojo.setCurrentNodeName(StringUtils.defaultIfBlank(currentNodeName, Constants.EOF_NODENAME));
        taskObjectPojo.setApplyTitle(processObject.getApplyTitle());
        taskObjectPojo.setApplicant(processObject.getCreator());
        taskObjectPojo.setTemplateName(processObject.getTemplateName());
    }

    /**
     * fixme 待修改为数据库表获取数据
     * 获取流程信息.
     * @return 流程信息
     **/
    @Override
    public List<ItemInfo> getFlowInfo() {
        return Arrays.stream(BusinessprocessEnum.values())
            .map(e -> new ItemInfo(e.getName(), e.getValue()))
            .collect(Collectors.toList());
    }

    /**
     * 获取流程状态.
     * @return 流程状态
     **/
    @Override
    public List<ItemInfo> getFlowState() {
        return Arrays.stream(ProcessStatusThree.values())
            .map(e -> new ItemInfo(e.getName(), e.getValue()))
            .collect(Collectors.toList());
    }
}
